package com.atguigu.gulimall.product.service.impl;

import com.atguigu.common.exception.ExceptionCast;
import com.atguigu.common.exception.ExceptionCodeEnum;
import com.atguigu.gulimall.product.service.CategoryBrandRelationService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.atguigu.common.utils.PageUtils;
import com.atguigu.common.utils.Query;

import com.atguigu.gulimall.product.dao.CategoryDao;
import com.atguigu.gulimall.product.entity.CategoryEntity;
import com.atguigu.gulimall.product.service.CategoryService;


@Service("categoryService")
public class CategoryServiceImpl extends ServiceImpl<CategoryDao, CategoryEntity> implements CategoryService {


    @Autowired
    private CategoryBrandRelationService categoryBrandRelationService;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<CategoryEntity> page = this.page(
                new Query<CategoryEntity>().getPage(params),
                new QueryWrapper<CategoryEntity>()
        );

        return new PageUtils(page);
    }

    @Override
    public List<CategoryEntity> listWithTree() {

        QueryWrapper<CategoryEntity> queryWrapper = new QueryWrapper<CategoryEntity>();
        queryWrapper.eq("show_status", "1");
        //所有分类 三级分类
        List<CategoryEntity> entities = baseMapper.selectList(queryWrapper);

        //将分类按照树形结构组织
        List<CategoryEntity> parentEntity = new ArrayList<CategoryEntity>();

        for (CategoryEntity entity : entities) {
            if (entity.getParentCid() == 0) {
                parentEntity.add(entity);
            }
        }

        parentEntity.sort((o1, o2) -> {
            if (o1.getSort() == null) {
                o1.setSort(0);
            }

            if (o2.getSort() == null) {
                o2.setSort(0);
            }

            return o1.getSort() - o2.getSort();
        });

        parentEntity = listWithTree(parentEntity, entities);

        for (CategoryEntity pEntity : parentEntity) {
            List<CategoryEntity> children = listWithTree(pEntity.getChildren(), entities);
            children.sort((o1, o2) -> {
                if (o1.getSort() == null) {
                    o1.setSort(0);
                }

                if (o2.getSort() == null) {
                    o2.setSort(0);
                }

                return o1.getSort() - o2.getSort();
            });
            pEntity.setChildren(children);
        }

        return parentEntity;
    }

    @Override
    public void deleteLogicByIds(Long[] catIds) {
        // 如果存在非子节点，不能删除

        if (hasParentNode(catIds)) {
            ExceptionCast.exception("包含非叶子节点分类，不能删除", 400);
        }

        CategoryEntity entity = new CategoryEntity();
        entity.setShowStatus(0);
        for (Long catId : catIds) {
            entity.setCatId(catId);
            baseMapper.updateById(entity);
        }

    }

    @Override
    public void deleteByIds(Long[] catIds) {

        // 如果存在非子节点，不能删除
        if (hasParentNode(catIds)) {
            ExceptionCast.exception("包含非叶子节点分类，不能删除", 400);
        }

        for (Long catId : catIds) {

            if (findOneById(catId) != null) {
                baseMapper.deleteById(catId);
                //级联删除 分类-品牌 数据
                categoryBrandRelationService.deleteByCatId(catId);
            }
        }
    }

    @Override
    public List<Long> getCategoryPathById(Long catId) {
        if (catId == null) {
            ExceptionCast.exception(ExceptionCodeEnum.ILLEGAL_ARGS_EXCEPTION.getMsg(), ExceptionCodeEnum.ILLEGAL_ARGS_EXCEPTION.getCode());
        }

        Stack<Long> stack = new Stack<Long>();

        CategoryEntity entity = baseMapper.selectById(catId);

        if (entity == null) {
            return new ArrayList<Long>();
        }

        stack.push(catId);

        while (entity.getParentCid() != 0) {

            entity = baseMapper.selectById(entity.getParentCid());
            stack.push(entity.getCatId());
        }

        List<Long> paths = new ArrayList<Long>();

        while (!stack.isEmpty()) {
            paths.add(stack.pop());
        }

        return paths;
    }

    @Override
    public CategoryEntity findOneById(Long catId) {
        return baseMapper.selectById(catId);
    }

    @Override
    public void updateDetailById(CategoryEntity category) {
        CategoryEntity oldEntity = findOneById(category.getCatId());
        baseMapper.updateById(category);

        if (!oldEntity.getName().equals(category.getName())) {
            categoryBrandRelationService.updateCateNameByCatId(category.getCatId(),category.getName());
        }
    }

    private boolean hasParentNode(Long[] catIds) {

        for (Long catId : catIds) {

            QueryWrapper<CategoryEntity> queryWrapper = new QueryWrapper<CategoryEntity>();
            queryWrapper.eq("parent_cid", catId);
            Integer integer = baseMapper.selectCount(queryWrapper);
            if (integer != 0) {
                return true;
            }
        }
        return false;
    }

    private List<CategoryEntity> listWithTree(List<CategoryEntity> parentEntity, List<CategoryEntity> root) {

        for (CategoryEntity entity : parentEntity) {

            List<CategoryEntity> children = new ArrayList<CategoryEntity>();

            for (CategoryEntity rootEntity : root) {

                if (rootEntity.getParentCid().longValue() == entity.getCatId().longValue()) {
                    children.add(rootEntity);
                }
            }
            entity.setChildren(children);
        }
        return parentEntity;
    }
}